/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _H_LIBZLANG_DATABASE_
#define _H_LIBZLANG_DATABASE_

#include "zlang.h"

#include "commonpool.h"

#include "cdbc.h"

struct ZlangObject_database;
struct ZlangObject_dbsession;
struct ZlangObject_dbresult;

#define ZLANG_OBJECT_database	"database"
#define ZLANG_OBJECT_dbsession	"dbsession"
#define ZLANG_OBJECT_dbresult	"dbresult"

#define EXCEPTION_MESSAGE_GET_DATABASE_DRIVER				"database driver not found"
#define EXCEPTION_MESSAGE_RECONNECT_LAST_SESSION_FAILED			"reconnect last session failed"
#define EXCEPTION_MESSAGE_CREATE_AND_START_CONNECTION_POOL_FAILED	"create and start connection pool failed"
#define EXCEPTION_MESSAGE_FETCH_CONNECTION_SESSION_FAILED		"fetch connection session failed"
#define EXCEPTION_MESSAGE_NO_CONNECTION_POOL				"no connection pool"
#define EXCEPTION_MESSAGE_BEGIN_TRANSACTION_FAILED			"begin transaction failed"
#define EXCEPTION_MESSAGE_GIVEBACK_CONNECTION_SESSION_FAILED		"giveback connection session failed"
#define EXCEPTION_MESSAGE_EXECUTE_SQL					"execute sql failed"

DLLEXPORT ZlangImportObjectsFunction ZlangImportObjects;
int ZlangImportObjects( struct ZlangRuntime *rt );

struct ZlangDirectProperty_database
{
	unsigned char			assistant_thread_enable ;
	int32_t				min_idle_connections_count ;
	int32_t				max_idle_connections_count ;
	int32_t				max_connections_count ;
	int32_t				max_idle_timeval ;
	int32_t				watch_idle_timeval ;
	int32_t				inspect_timeval ;
	
	struct ZlangDirectProperty_dbsession	*last_session_direct_prop ;
} ;

#define CONNECTIONSPOOL_MIN_IDLE_CONNECTIONS_COUNT_DEFAULT	1
#define CONNECTIONSPOOL_MAX_IDLE_CONNECTIONS_COUNT_DEFAULT	2
#define CONNECTIONSPOOL_MAX_CONNECTIONS_COUNT_DEFAULT		2
#define CONNECTIONSPOOL_MAX_IDLE_TIMEVAL_DEFAULT		5*60
#define CONNECTIONSPOOL_WATCH_IDLE_TIMEVAL_DEFAULT		60
#define CONNECTIONSPOOL_INSPECT_TIMEVAL_DEFAULT			1000*1000 /* 1s */

struct ZlangDirectProperty_dbsession
{
	struct DatabaseDriver			*db_driver ;
	struct ZlangRuntime			*rt ;
	char					*db_host ;
	int32_t					db_port ;
	char					*db_user ;
	char					*db_pass ;
	char					*db_name ;
	
	unsigned char				assistant_thread_enable ;
	int32_t					min_idle_connections_count ;
	int32_t					max_idle_connections_count ;
	int32_t					max_connections_count ;
	int32_t					max_idle_timeval ;
	int32_t					watch_idle_timeval ;
	int32_t					inspect_timeval ;
	struct CommonPool			*connections_pool ;
	
	unsigned char				in_transaction ;
	struct DatabaseConnectionContext	*db_conn_ctx ;
	
	struct ZlangDirectProperty_database	*ref_database_direct_prop ;
	
	struct timeval				sql_elapse ;
	struct timeval				total_sql_elapse ;
} ;

int dbsession_Disconnect( struct ZlangRuntime *rt , struct ZlangDirectProperty_dbsession *dbsession_direct_prop );
int dbsession_Reconnect( struct ZlangRuntime *rt , struct ZlangDirectProperty_dbsession *dbsession_direct_prop );

struct ZlangDirectProperty_dbresult
{
	int				row_count ;
	int				col_count ;
	struct FieldInfo		*query_field_set ;
	char				**query_result_set ;
	int				affected_count ;
} ;

int CreateAndStartCommonPool( struct ZlangDirectProperty_dbsession *dbsession_direct_prop );

extern struct ZlangDirectFunctions direct_funcs_dbsession ;
extern struct ZlangDirectFunctions direct_funcs_dbresult ;

#endif

